#include "VulkanShader.h"
#include "VulkanDevice.h"

namespace Alice
{
    std::unordered_map<std::string,VulkanShader*> VulkanShader::mCachedShaders;
    template VulkanVertexShader* GetOrCreateVulkanShader<VulkanVertexShader>(VulkanDevice*inDevice,const char *inShaderPath,unsigned char* inCode, int32 inCodeDataLen);
    template VulkanPixelShader* GetOrCreateVulkanShader<VulkanPixelShader>(VulkanDevice*inDevice,const char *inShaderPath,unsigned char* inCode, int32 inCodeDataLen);
    VulkanShader::VulkanShader(VulkanDevice*inDevice,EShaderFrequency inFrequency,unsigned char* inCode, int32 inCodeSizeLen)
        :mDevice(inDevice),mFrequency(inFrequency)
    {
        VkShaderModuleCreateInfo ModuleCreateInfo;
        ZeroVulkanStruct(ModuleCreateInfo, VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
        ModuleCreateInfo.codeSize = size_t(inCodeSizeLen);
        ModuleCreateInfo.pCode = (uint32*)inCode;
        VERIFYVULKANRESULT(vkCreateShaderModule(mDevice->GetDevice(), &ModuleCreateInfo, nullptr, &mShaderModule));
    }
    template<typename T>
    T* GetOrCreateVulkanShader(VulkanDevice*inDevice,const char *inShaderPath,unsigned char* inCode, int32 inCodeDataLen)
    {
        auto iter=VulkanShader::mCachedShaders.find(inShaderPath);
        if(iter!=VulkanShader::mCachedShaders.end())
        {
            return reinterpret_cast<T*>(iter->second);
        }
        T*shader=new T(inDevice,inCode,inCodeDataLen);
        return shader;
    }
}